package com.fling.block;

import java.util.ArrayList;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.fling.Constants;
import com.fling.Locator;
import com.fling.objects.Coin;
import com.fling.objects.Hero;
import com.fling.observer.Subject;

public class BlockPattern implements Constants {

	private ArrayList<BlockRow> rows;
	private float patternTimer;
	private Hero hero;
	private Subject subject;
	private Coin coin;

	public static int HARD_PATTERNS = 15;
	public static int EASY_PATTERNS = 10;
	public static float SECONDS_PER_PATTERN = 7.8F;
	public static float SECONDS_PER_DESIGN_PATTERN = 2.6F;

	public BlockPattern(Hero hero, Subject subject) {
		rows = new ArrayList<BlockRow>();
		patternTimer = 0;
		this.hero = hero;
		this.subject = subject;
		coin = null;
	}

	public void buildPattern() {
		int choice = 0;
		if (Locator.difficulty == Locator.HARD) {
			choice = MathUtils.random(1, HARD_PATTERNS);
		} else {
			choice = MathUtils.random(1, EASY_PATTERNS);
		}
		rows = choosePattern(choice);
	}

	public void buildRandomPattern() {
		BlockRow r = null;
		// put a coin somewhere in the 4 rows
		int coinRow = MathUtils.random(0, 6);
		if (coinRow % 2 != 0) {
			coinRow--;
		}
		for (int i = 0; i < 7; i++) {
			r = new BlockRow(hero, subject);

			// add one row that has a coin
			if (i == coinRow) {
				Vector2 coinPos = r.buildRowWithCoin(i * 2);
				coin = new Coin(coinPos);
				rows.add(r);
			}
			// every other row is blank
			else if (i % 2 == 0) {
				r.buildRow(i * 2);
				rows.add(r);
			}

		}
		patternTimer = rows.size() * SECONDS_PER_PATTERN;
	}

	public void delete() {
		for (BlockRow b : rows) {
			b.delete();
		}
		if (coin.isExists()) {
			coin.delete();
		}
	}

	public boolean isBelowScreen() {
		if (rows.size() > 0) {
			return rows.get(rows.size() - 1).isBelowScreen();
		} else {
			return false;
		}
	}

	public void update(float delta) {
		for (BlockRow b : rows) {
			b.update(delta);
		}
		if (Locator.difficulty == Locator.HARD) {
			coin.update(delta);
		}
	}

	public void render(SpriteBatch sb) {
		for (BlockRow b : rows) {
			b.render(sb);
		}
		if (Locator.difficulty == Locator.HARD) {
			coin.render(sb);
		}
	}

	public float getPatternTimer() {
		return patternTimer;
	}

	public void setPatternTimer(float patternTimer) {
		this.patternTimer = patternTimer;
	}

	private ArrayList<BlockRow> choosePattern(int choice) {
		ArrayList<BlockRow> pattern = new ArrayList<BlockRow>();
		BlockRow r = null;
		int x_pos = 0;
		switch (choice) {
		case 1:
			for (int i = 0; i < 3; i++) {
				r = new BlockRow(hero, subject);
				r.buildStructuredRow(new int[] { 1, 2 }, i * 2);
				pattern.add(r);
			}
			patternTimer = 5 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 0;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 3;
			}
			addCoin(x_pos, 1);
			break;

		case 2:
			for (int i = 0; i < 3; i++) {
				r = new BlockRow(hero, subject);
				r.buildStructuredRow(new int[] { 0, 3 }, i * 2);
				pattern.add(r);
			}
			patternTimer = 5 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 2;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 1;
			}
			addCoin(x_pos, 1);
			break;
		case 3:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 4);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1 }, 8);
			pattern.add(r);
			patternTimer = 9 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(1, 4);
			break;
		case 4:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 4);
			pattern.add(r);
			patternTimer = 5 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(1, 1);
			break;
		case 5:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 3);
			pattern.add(r);
			patternTimer = 4 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 1;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 2;
			}
			addCoin(x_pos, 2);
			break;
		case 6:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 2, 3 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 2, 3 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 4);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 5);
			pattern.add(r);
			patternTimer = 6 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(1, 4);
			break;
		case 7:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 4);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 7);
			pattern.add(r);
			patternTimer = 8 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 0;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 3;
			}
			addCoin(x_pos, 7);
			break;
		case 8:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 5);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 8);
			pattern.add(r);
			patternTimer = 9 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 1;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 2;
			}
			addCoin(x_pos, 3);
			break;
		case 9:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 5);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 7);
			pattern.add(r);
			patternTimer = 8 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(2, 5);
			break;
		case 10:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 5);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 8);
			pattern.add(r);
			patternTimer = 9 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 1;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 2;
			}
			addCoin(x_pos, 0);
			break;
		case 11:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 2, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 2, 3 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 6);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 7);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 10);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1 }, 11);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 13);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 2, 3 }, 16);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2, 3 }, 17);
			pattern.add(r);
			patternTimer = 15 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(3, 9);
			break;
		case 12:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 2 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 5);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2, 3 }, 9);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2, 3 }, 10);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 3 }, 11);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 3 }, 12);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 3 }, 14);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 17);
			pattern.add(r);
			patternTimer = 15 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 1;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 2;
			}
			addCoin(x_pos, 13);
			break;
		case 13:
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 3 }, 0);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 3 }, 1);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 3 }, 2);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 3 }, 3);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1, 3 }, 4);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 8);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 1, 2 }, 10);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2 }, 14);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2 }, 15);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2 }, 16);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2 }, 17);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 18);
			pattern.add(r);
			patternTimer = 19 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			x_pos = 0;
			if (MathUtils.random(0, 1) == 1) {
				x_pos = 3;
			}
			addCoin(x_pos, 8);
			break;
		case 14:
			for (int i = 0; i < 5; i++) {
				r = new BlockRow(hero, subject);
				r.buildStructuredRow(new int[] { 0, 3 }, i * 2);
				pattern.add(r);
			}
			for (int i = 0; i < 4; i++) {
				r = new BlockRow(hero, subject);
				r.buildStructuredRow(new int[] { 2 }, i * 2 + 11);
				pattern.add(r);
			}
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,2 }, 18);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,2 }, 19);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,2 }, 20);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, 21);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 },22);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 24);
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 2, 3 }, 25);
			pattern.add(r);
			patternTimer = 23 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(1, 12);
			break;
		case 15:
			int j=0;
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,2 }, 0); j++;
			pattern.add(r);
			for (int i = 0; i < 3; i++) {
				r = new BlockRow(hero, subject);
				r.buildStructuredRow(new int[] { 1,2 }, i+j);
				pattern.add(r);
				
			} j+=6;
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,3 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1,3 }, j);j+=2;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0, 1 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,1,2 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,1,2 },j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0}, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,2,3 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,2,3 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,2,3 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0}, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0 }, j);j++;
			pattern.add(r);
			r = new BlockRow(hero, subject);
			r.buildStructuredRow(new int[] { 0,1,2 }, j);j++;
			pattern.add(r);
			patternTimer = 21 * SECONDS_PER_DESIGN_PATTERN;
			// add a coin
			addCoin(0, 2);
			break;
		default:
			break;
		}
		return pattern;
	}

	public void addCoin(float x_pos, float y_pos) {
		coin = new Coin(new Vector2(WALL_WIDTH * Locator.getxSpriteScale() + Locator.getBlockSpacing() * x_pos + BLOCK_WIDTH
				* Locator.getxSpriteScale() / 2, VIRTUAL_HEIGHT * Locator.getySpriteScale() + BLOCK_HEIGHT * Locator.getySpriteScale() * y_pos
				+ BLOCK_HEIGHT * Locator.getySpriteScale() / 2));
	}
}
